package ConnectivityEditor.Window;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import javax.media.opengl.GL2;
import Builder.MainCamera;
import Common.Ray3;
import Common.Vector3f;
import Connectivity.Axle;
import Connectivity.Connectivity;
import ConnectivityEditor.Connectivity.AxleT;
import LDraw.Support.MatrixMath;
import LDraw.Support.type.LDrawGridTypeT;
public class AxleRenderer extends DefaultConnectivityRenderer {
private Axle axle;
public AxleRenderer(MainCamera camera, Connectivity conn) {
super(camera, conn);
axle = (Axle) conn;
}
@Override
public void draw(GL2 gl2) {
if (axle.gettype() % 2 == 0) {// socket
if (conn.isSelected())
gl2.glColor3f(0.2f, 0.2f, 0.2f);
else
gl2.glColor3f(1f, 1f, 0);
} else {
if (conn.isSelected())
gl2.glColor3f(0.2f, 0.2f, 0.2f);
else
gl2.glColor3f(0f, 0f, 1f);
}
gl2.glLoadMatrixf(camera.getModelView(), 0);
if (axle.gettype() % 2 == 0) {// socket
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
for (Vector3f vertex : getAxleSocketVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
for (Vector3f vertex : getGuideVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
gl2.glBegin(GL2.GL_TRIANGLES);
for (Vector3f vertex : getCapVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
} else {// axle
// Draw Stud Disk (possible styles: FILL, LINE, POINT).
if (AxleT.byValue(axle.gettype()).toString().contains("Cross")) {
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
for (Vector3f vertex : getAxleBarVertices_Cross())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
} else if (AxleT.byValue(axle.gettype()).toString().contains("Pin")) {
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
for (Vector3f vertex : getAxleBarVertices_Pin())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
gl2.glBegin(GL2.GL_QUADS);
for (Vector3f vertex : getGuideVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
} else { // O axle
gl2.glBegin(GL2.GL_QUADS); // draw using triangles
for (Vector3f vertex : getAxleBarVertices_O())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
gl2.glBegin(GL2.GL_QUADS);
for (Vector3f vertex : getGuideVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
}
gl2.glBegin(GL2.GL_TRIANGLES);
for (Vector3f vertex : getCapVertices())
gl2.glVertex3f(vertex.x, vertex.y, vertex.z);
gl2.glEnd();
}
}
private Vector3f[] getCapVertices() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float diskRadius = LDrawGridTypeT.Medium.getXZValue();
Vector3f vertex = null;
int slice = 24;
if (axle.getstartCapped() == 1) {
vertex = new Vector3f();
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex);
vertices.add(vertex.add(
(float) (diskRadius * Math.cos((sliceIndex) * Math.PI
* 2 / (slice - 1))),
0,
(float) (diskRadius * Math.sin((sliceIndex) * Math.PI
* 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (diskRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (diskRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
}
}
if (axle.getendCapped() == 1) {
vertex = new Vector3f(0, -axle.getlength(), 0);
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex);
vertices.add(vertex.add(
(float) (diskRadius * Math.cos((sliceIndex) * Math.PI
* 2 / (slice - 1))),
0,
(float) (diskRadius * Math.sin((sliceIndex) * Math.PI
* 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (diskRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (diskRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
}
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = axle.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
private Vector3f[] getAxleBarVertices_O() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float cylinderRadius = LDrawGridTypeT.Medium.getXZValue() / 1.6f;
final float cylinderHeight = -axle.getlength();
Vector3f vertex;
int slice = 24;
vertex = new Vector3f();
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex * Math.PI * 2
/ (slice - 1))),
0,
(float) (cylinderRadius * Math.sin(sliceIndex * Math.PI * 2
/ (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex * Math.PI * 2
/ (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin(sliceIndex * Math.PI * 2
/ (slice - 1)))));
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = axle.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
private Vector3f[] getAxleBarVertices_Pin() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float cylinderRadius = LDrawGridTypeT.Medium.getXZValue() / 2f;
final float cylinderHeight = -axle.getlength();
Vector3f vertex;
int slice = 24;
vertex = new Vector3f();
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex * Math.PI * 2
/ (slice - 1))),
0,
(float) (cylinderRadius * Math.sin(sliceIndex * Math.PI * 2
/ (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex * Math.PI * 2
/ (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin(sliceIndex * Math.PI * 2
/ (slice - 1)))));
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = axle.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
private Vector3f[] getAxleBarVertices_Cross() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float radius = LDrawGridTypeT.Medium.getXZValue() / 2f;
final float length = axle.getlength();
final float thickness = 2;
vertices.add(new Vector3f(-radius, 0, thickness / 2));
vertices.add(new Vector3f(-radius, 0, -thickness / 2));
vertices.add(new Vector3f(-radius, -length, -thickness / 2));
vertices.add(new Vector3f(-radius, -length, thickness / 2));
vertices.add(new Vector3f(radius, 0, thickness / 2));
vertices.add(new Vector3f(radius, 0, -thickness / 2));
vertices.add(new Vector3f(radius, -length, -thickness / 2));
vertices.add(new Vector3f(radius, -length, thickness / 2));
vertices.add(new Vector3f(-radius, 0, -thickness / 2));
vertices.add(new Vector3f(radius, 0, -thickness / 2));
vertices.add(new Vector3f(radius, -length, -thickness / 2));
vertices.add(new Vector3f(-radius, -length, -thickness / 2));
vertices.add(new Vector3f(-radius, 0, thickness / 2));
vertices.add(new Vector3f(radius, 0, thickness / 2));
vertices.add(new Vector3f(radius, -length, thickness / 2));
vertices.add(new Vector3f(-radius, -length, thickness / 2));
vertices.add(new Vector3f(-thickness / 2, 0, radius));
vertices.add(new Vector3f(-thickness / 2, 0, -radius));
vertices.add(new Vector3f(-thickness / 2, -length, -radius));
vertices.add(new Vector3f(-thickness / 2, -length, radius));
vertices.add(new Vector3f(thickness / 2, 0, radius));
vertices.add(new Vector3f(thickness / 2, 0, -radius));
vertices.add(new Vector3f(thickness / 2, -length, -radius));
vertices.add(new Vector3f(thickness / 2, -length, radius));
vertices.add(new Vector3f(-thickness / 2, 0, -radius));
vertices.add(new Vector3f(thickness / 2, 0, -radius));
vertices.add(new Vector3f(thickness / 2, -length, -radius));
vertices.add(new Vector3f(-thickness / 2, -length, -radius));
vertices.add(new Vector3f(-thickness / 2, 0, radius));
vertices.add(new Vector3f(thickness / 2, 0, radius));
vertices.add(new Vector3f(thickness / 2, -length, radius));
vertices.add(new Vector3f(-thickness / 2, -length, radius));
vertices.add(new Vector3f(-thickness / 2, 0, -thickness / 2));
vertices.add(new Vector3f(thickness / 2, 0, -thickness / 2));
vertices.add(new Vector3f(thickness / 2, 0, thickness / 2));
vertices.add(new Vector3f(-thickness / 2, 0, thickness / 2));
vertices.add(new Vector3f(-thickness / 2, -length, -thickness / 2));
vertices.add(new Vector3f(thickness / 2, -length, -thickness / 2));
vertices.add(new Vector3f(thickness / 2, -length, thickness / 2));
vertices.add(new Vector3f(-thickness / 2, -length, thickness / 2));
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = axle.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
@Override
public boolean isHitted(MainCamera camera, float screenX, float screenY,
FloatBuffer distance) {
Ray3 ray = camera.getRay(screenX, screenY);
FloatBuffer distanceTemp = FloatBuffer.allocate(1);
boolean isHitted = false;
if (axle.gettype() % 2 == 0) {// socket
Vector3f[] vertices = getAxleSocketVertices();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i + 2],
vertices[(i + 3)], vertices[i], distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
vertices = getGuideVertices();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i + 2],
vertices[(i + 3)], vertices[i], distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
vertices = getCapVertices();
for (int i = 0; i < vertices.length; i += 3) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
} else {// axle
// Draw Stud Disk (possible styles: FILL, LINE, POINT).
if (AxleT.byValue(axle.gettype()).toString().contains("Cross")) {
Vector3f[] vertices = getAxleBarVertices_Cross();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray,
vertices[i + 2], vertices[(i + 3)], vertices[i],
distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
} else if (AxleT.byValue(axle.gettype()).toString().contains("Pin")) {
Vector3f[] vertices = getAxleBarVertices_Pin();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray,
vertices[i + 2], vertices[(i + 3)], vertices[i],
distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
vertices = getGuideVertices();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray,
vertices[i + 2], vertices[(i + 3)], vertices[i],
distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
} else { // O axle
Vector3f[] vertices = getAxleBarVertices_O();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray,
vertices[i + 2], vertices[(i + 3)], vertices[i],
distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
vertices = getGuideVertices();
for (int i = 0; i < vertices.length; i += 4) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
if (MatrixMath.V3RayIntersectsTriangle(ray,
vertices[i + 2], vertices[(i + 3)], vertices[i],
distanceTemp, null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
}
Vector3f[] vertices = getCapVertices();
for (int i = 0; i < vertices.length; i += 3) {
if (MatrixMath.V3RayIntersectsTriangle(ray, vertices[i],
vertices[(i + 1)], vertices[(i + 2)], distanceTemp,
null)) {
if (distance != null)
if (distanceTemp.get(0) < distance.get(0))
distance.put(0, distanceTemp.get(0));
isHitted = true;
}
}
}
lastHittedDistance = distance.get(0);
return isHitted;
}
private Vector3f[] getGuideVertices() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float cylinderRadius = LDrawGridTypeT.Medium.getXZValue() / 1.6f;
Vector3f vertex;
int slice = 24;
vertex = new Vector3f();
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex.add(
(float) (cylinderRadius / 1.6f * Math.cos((sliceIndex)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius / 1.6f * Math.sin((sliceIndex)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius / 1.6f * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius / 1.6f * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex) * Math.PI
* 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex) * Math.PI
* 2 / (slice - 1)))));
}
vertex = new Vector3f(0, -axle.getlength(), 0);
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex.add(
(float) (cylinderRadius / 1.6f * Math.cos((sliceIndex)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius / 1.6f * Math.sin((sliceIndex)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius / 1.6f * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius / 1.6f * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex) * Math.PI
* 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex) * Math.PI
* 2 / (slice - 1)))));
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = axle.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
private Vector3f[] getAxleSocketVertices() {
ArrayList<Vector3f> vertices = new ArrayList<Vector3f>();
final float cylinderRadius = LDrawGridTypeT.Medium.getXZValue() / 1.6f;
final float cylinderHeight = -axle.getlength();
Vector3f vertex;
int slice = 24;
vertex = new Vector3f();
for (int sliceIndex = 0; sliceIndex < slice - 1; sliceIndex++) {
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex * Math.PI * 2
/ (slice - 1))),
0,
(float) (cylinderRadius * Math.sin(sliceIndex * Math.PI * 2
/ (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
0,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos((sliceIndex + 1)
* Math.PI * 2 / (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin((sliceIndex + 1)
* Math.PI * 2 / (slice - 1)))));
vertices.add(vertex.add(
(float) (cylinderRadius * Math.cos(sliceIndex * Math.PI * 2
/ (slice - 1))),
cylinderHeight,
(float) (cylinderRadius * Math.sin(sliceIndex * Math.PI * 2
/ (slice - 1)))));
}
Vector3f[] retArray = new Vector3f[vertices.size()];
for (int i = 0; i < vertices.size(); i++) {
retArray[i] = axle.getTransformMatrix().transformPoint(
vertices.get(i));
}
return retArray;
}
}